package tunnel

import (
	"fmt"
	"log"

	"internal-net-bridge-server/internal/models"
	"internal-net-bridge-server/internal/tunnel/core"
	httpProto "internal-net-bridge-server/internal/tunnel/protocols/http"
	tcpProto "internal-net-bridge-server/internal/tunnel/protocols/tcp"
)

// ========================================
// 协议工厂 - 创建协议监听器
// ========================================

// ProtocolFactory 协议工厂
type ProtocolFactory struct {
	quicServer       *QUICTunnelServer
	forwarderFactory *ForwarderFactory // 🔥 转发器工厂
}

// NewProtocolFactory 创建协议工厂
func NewProtocolFactory(quicServer *QUICTunnelServer) *ProtocolFactory {
	return &ProtocolFactory{
		quicServer:       quicServer,
		forwarderFactory: NewForwarderFactory(quicServer), // 🔥 初始化转发器工厂
	}
}

// CreateListener 根据协议类型创建监听器
func (f *ProtocolFactory) CreateListener(tunnel *models.Tunnel) (core.ProtocolListener, error) {
	if tunnel.PublicPort == "" || tunnel.PublicPort == "0" {
		return nil, fmt.Errorf("公共端口未配置")
	}

	var listener core.ProtocolListener
	var forwarder core.QUICForwarder

	switch tunnel.ProtocolType {
	case "tcp":
		log.Printf("🔌 [工厂] 创建TCP监听器: 端口=%s, 隧道ID=%s", tunnel.PublicPort, tunnel.ID)
		forwarder = f.forwarderFactory.CreateTCPForwarder()
		listener = tcpProto.NewListener(tunnel.ID, tunnel.PublicPort, forwarder)

	case "http", "https", "":
		// 默认使用HTTP监听器
		log.Printf("🌐 [工厂] 创建HTTP监听器: 端口=%s, 隧道ID=%s", tunnel.PublicPort, tunnel.ID)
		forwarder = f.forwarderFactory.CreateHTTPForwarder()
		listener = httpProto.NewListener(tunnel.ID, tunnel.PublicPort, forwarder)

	default:
		return nil, fmt.Errorf("不支持的协议类型: %s", tunnel.ProtocolType)
	}

	return listener, nil
}

// StartListener 启动监听器
func (f *ProtocolFactory) StartListener(listener core.ProtocolListener) error {
	if listener == nil {
		return fmt.Errorf("监听器为空")
	}

	if err := listener.Start(); err != nil {
		return fmt.Errorf("启动%s监听器失败: %w", listener.GetProtocolType(), err)
	}

	log.Printf("✅ [工厂] %s监听器已启动: 端口=%s", listener.GetProtocolType(), listener.GetPort())
	return nil
}

// StopListener 停止监听器
func (f *ProtocolFactory) StopListener(listener core.ProtocolListener) error {
	if listener == nil {
		return nil
	}

	if err := listener.Stop(); err != nil {
		return fmt.Errorf("停止%s监听器失败: %w", listener.GetProtocolType(), err)
	}

	log.Printf("🛑 [工厂] %s监听器已停止: 端口=%s", listener.GetProtocolType(), listener.GetPort())
	return nil
}
